package com.disease.api.service.config;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.disease.api.service.entity.BaseUser;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
public class JwtService {
    // token秘钥  太短会报错
    private static String secretKey="qwerasdfdxzvdfajjlkjeiojznvxndjkfaowijeiodl";

    //jwt过期时间，单位毫秒
//    private static long ttlMillis=1*60*60*1000;
    private static long ttlMillis=-1;

    private static final String USER_NAME="userName";

    public static final String BEARER="Bearer ";

    // 使用 Guava Cache 存储有效的刷新令牌
//    private static final Cache<String, String> validRefreshTokens = CacheBuilder.newBuilder()
//           .expireAfterWrite(2, TimeUnit.HOURS)
//            .build();
    private static final Map<String, String> validRefreshTokens = new HashMap<>();


    /**
     * 生成Jwt的方法
     *
     * @param id
     *            用户ID
     *            用户昵称
     * @return Token String 凭证
     */
    public static String createJWT(String id, BaseUser user) {
        // 签名方法 HS256
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        // 生成Jwt的时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        // 生成秘钥
        SecretKey signingKey = Keys.hmacShaKeyFor(secretKey.getBytes());
        // 设置JWT所存储的信息
        JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now).signWith(signingKey,
                signatureAlgorithm);
        builder.claim(USER_NAME, JSONObject.toJSONString(user)); //存储自定义信息
        // 设置过期时间
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        String token=BEARER+builder.compact();
        validRefreshTokens.put(token, JSONObject.toJSONString(user));
        // 构建JWT并将其序列化为紧凑的URL安全字符串
        return token;
    }


    /**
     * 解析jwt
     * @param token
     * @return
     */
    public static BaseUser parseToken(String token){
        BaseUser baseUser=null;
//        if(!StringUtils.isBlank(validRefreshTokens.getIfPresent(token))){}
        if(validRefreshTokens.containsKey(token)){
            try {
                if(token.startsWith(BEARER)){
                    token=token.substring(7);
                }
                //密钥实例
                SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes());
                Jws<Claims> claimsJws = Jwts.parser()
                        .verifyWith(key)  //设置签名的密钥
                        .build()
                        .parseSignedClaims(token); //设置要解析的jwt
                String userName = claimsJws.getPayload().get(USER_NAME).toString();
                baseUser=JSONObject.parseObject(userName,BaseUser.class);
                baseUser.setId(claimsJws.getPayload().getId());
            }catch (Exception e){
                log.error("token解析失败",e.getMessage());
            }
        }
        return baseUser;
    }

    /**
     * 根据userId和openid生成token
     */
    public static String generateToken(String id,BaseUser userName) {
        return createJWT(id,userName);
    }

    // 登出，使刷新令牌失效
    public static void logout(String token) {
//        validRefreshTokens.invalidate(token);
        validRefreshTokens.remove(token);
    }


    public static void main(String[] args) {
        String token = createJWT("1", new BaseUser());
        BaseUser baseUser = parseToken(token);
        System.out.println("============>"+baseUser);
        logout(token);
        BaseUser baseUser1 = parseToken(token);
        System.out.println("============>"+baseUser1);
    }

}
